﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;

namespace Isuka.Excel
{
    /// <summary>
    /// Excel ワークシート
    /// </summary>
    public partial class XWorksheet
        : ExcelObject
        , IXGrid
    {
        readonly XWorkbook workbook;
        readonly XRange cells;

        internal XWorksheet(XWorkbook workbook, object worksheet)
            : base(workbook.Application, worksheet)
        {
            Contract.Requires(workbook != null);
            Contract.Requires(worksheet != null);

            this.workbook = workbook;
            this.cells = new XRange(this, Object.Cells);
        }

        /// <summary>
        /// ワークシート内の全てのセル
        /// </summary>
        public XRange Cells
        {
            get
            {
                Contract.Ensures(Contract.Result<XRange>() != null);
                VerifyNotDisposed();
                return cells;
            }
        }

        /// <summary>
        /// ワークシート名
        /// </summary>
        public string Name
        {
            get
            {
                VerifyNotDisposed();
                return Object.Name;
            }
            set
            {
                VerifyNotDisposed();
                Object.Name = value;
            }
        }

        public XRange Range(XRange begin, XRange end)
        {
            Contract.Requires<ArgumentNullException>(begin != null, "begin");
            Contract.Requires<ArgumentNullException>(end != null, "end");
            Contract.Ensures(Contract.Result<XRange>() != null);

            VerifyNotDisposed();
            object cells = Object.Range(begin.Address, end.Address);
            Contract.Assume(cells != null);
            return new XRange(this, cells);
        }

        public XWorkbook Workbook
        {
            get { return workbook; }
        }

        #region AutomationObject メンバー

        protected override void PreReleaseObject()
        {
            if (docEvents != null)
            {
                docEvents.Dispose();
            }
            base.PreReleaseObject();
        }

        #endregion

        #region IXGrid メンバー

        public XRange this[int rowIndex, int columnIndex]
        {
            get
            {
                Gate.Positive(rowIndex);
                Gate.Positive(columnIndex);
                VerifyNotDisposed();
                return cells[rowIndex, columnIndex];
            }
        }

        public XRange this[int rowIndex, string columnIndex]
        {
            get
            {
                Gate.Positive(rowIndex);
                VerifyNotDisposed();
                return cells[rowIndex, columnIndex];
            }
        }

        public XRange Columns
        {
            get
            {
                VerifyNotDisposed();
                return cells.Columns;
            }
        }

        public XRange Rows
        {
            get
            {
                VerifyNotDisposed();
                return cells.Rows;
            }
        }

        #endregion

        #region IEnumerable<XRange> メンバー

        public IEnumerator<XRange> GetEnumerator()
        {
            VerifyNotDisposed();
            return cells.GetEnumerator();
        }

        #endregion

        #region IEnumerable メンバー

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region ContractInvariantMethod

        [ContractInvariantMethod]
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Required for code contracts.")]
        [DebuggerStepThrough]
        private void ObjectInvariant()
        {
            Contract.Invariant(workbook != null);
            Contract.Invariant(cells != null);
        }

        #endregion

    }
}
